using MediatR;
using Microsoft.Extensions.Logging;
using RBAC.Domain.OutboundManage;
using RBAC.ErrorCode;
using RBAC.Interstructrue.Base;
using RBAC.Write.Api.Application.Command.ERP.OutboundManagement;
using System.Data;
using ClosedXML.Excel;

namespace RBAC.Write.Api.Application.Handler.ERP.OutboundManagement
{
    /// <summary>
    /// 导出销售出库处理器
    /// </summary>
    public class ExportSalesOutboundHandler : IRequestHandler<ExportSalesOutboundCommand, APIResult<byte[]>>
    {
        private readonly IBaseRepository<SalesOutbound> repository;
        private readonly ILogger<ExportSalesOutboundHandler> logger;

        public ExportSalesOutboundHandler(IBaseRepository<SalesOutbound> repository,
            ILogger<ExportSalesOutboundHandler> logger)
        {
            this.repository = repository;
            this.logger = logger;
        }

        public Task<APIResult<byte[]>> Handle(ExportSalesOutboundCommand request, CancellationToken cancellationToken)
        {
            var result = new APIResult<byte[]>();
            try
            {
                logger.LogInformation("开始导出销售出库，PageIndex={PageIndex}, PageSize={PageSize}, ExportAll={ExportAll}", request.PageIndex, request.PageSize, request.ExportAll);

                if (request.PageSize > 10000 && !request.ExportAll)
                {
                    result.Code = APIEnums.Error;
                    result.Msg = "单次导出数量不能超过10000条，如需导出更多请设置ExportAll=true或分批导出";
                    return Task.FromResult(result);
                }

                // 若指定了某年某月，折算为起止日期（当未显式传入Start/End时）
                if (request.Year.HasValue && request.Month.HasValue)
                {
                    var y = request.Year.Value;
                    var m = request.Month.Value;
                    if (m >= 1 && m <= 12)
                    {
                        var first = new DateTime(y, m, 1);
                        var last = first.AddMonths(1).AddDays(-1);
                        request.StartDate ??= first;
                        request.EndDate ??= last;
                    }
                }

                var where = BuildWhereClause(request);
                var parameters = BuildParameters(request);

                IEnumerable<SalesOutbound> data;
                if (request.ExportAll)
                {
                    data = repository.GetAll(where, parameters);
                }
                else
                {
                    var paged = repository.GetPaged(request.PageIndex, request.PageSize, where, request.OrderBy, parameters);
                    data = paged.Data;
                }

                if (data == null || !data.Any())
                {
                    result.Code = APIEnums.Error;
                    result.Msg = "没有符合条件的数据可导出";
                    return Task.FromResult(result);
                }

                var dt = new DataTable("销售出库");
                dt.Columns.Add("单据编码");
                dt.Columns.Add("单据日期");
                dt.Columns.Add("客户名称");
                dt.Columns.Add("单据状态");
                dt.Columns.Add("业务状态");
                dt.Columns.Add("仓库");
                dt.Columns.Add("发货单号");
                dt.Columns.Add("发货类型");
                dt.Columns.Add("备注");
                dt.Columns.Add("创建时间");
                dt.Columns.Add("创建人");

                foreach (var o in data)
                {
                    var row = dt.NewRow();
                    row["单据编码"] = o.OrderCode ?? string.Empty;
                    row["单据日期"] = o.OrderDate?.ToString("yyyy-MM-dd") ?? string.Empty;
                    row["客户名称"] = o.CustomerName ?? string.Empty;
                    row["单据状态"] = o.OrderStatus ?? string.Empty;
                    row["业务状态"] = o.BusinessStatus ?? string.Empty;
                    row["仓库"] = o.Warehouse ?? string.Empty;
                    row["发货单号"] = o.DeliveryNo ?? string.Empty;
                    row["发货类型"] = o.DeliveryType ?? string.Empty;
                    row["备注"] = o.Remark ?? string.Empty;
                    row["创建时间"] = o.CreateTime.ToString("yyyy-MM-dd HH:mm:ss");
                    row["创建人"] = o.CreateUser ?? string.Empty;
                    dt.Rows.Add(row);
                }

                byte[] bytes = ExportToExcel(dt);
                result.Code = APIEnums.Success;
                result.Msg = "导出销售出库成功";
                result.Data = bytes;
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "导出销售出库失败: {Message}", ex.Message);
                result.Code = APIEnums.Error;
                result.Msg = "导出销售出库失败: " + ex.Message;
            }

            return Task.FromResult(result);
        }

        private string BuildWhereClause(ExportSalesOutboundCommand request)
        {
            var conditions = new List<string>();
            if (!string.IsNullOrWhiteSpace(request.OrderCode)) conditions.Add("OrderCode LIKE @OrderCode");
            if (request.StartDate.HasValue) conditions.Add("OrderDate >= @StartDate");
            if (request.EndDate.HasValue) conditions.Add("OrderDate <= @EndDate");
            if (!string.IsNullOrWhiteSpace(request.OrderStatus)) conditions.Add("OrderStatus = @OrderStatus");
            if (!string.IsNullOrWhiteSpace(request.BusinessStatus)) conditions.Add("BusinessStatus = @BusinessStatus");
            if (!string.IsNullOrWhiteSpace(request.Warehouse)) conditions.Add("Warehouse = @Warehouse");
            return conditions.Count > 0 ? string.Join(" AND ", conditions) : string.Empty;
        }

        private object BuildParameters(ExportSalesOutboundCommand request)
        {
            var p = new Dictionary<string, object>();
            if (!string.IsNullOrWhiteSpace(request.OrderCode)) p["OrderCode"] = $"%{request.OrderCode}%";
            if (request.StartDate.HasValue) p["StartDate"] = request.StartDate.Value.Date;
            if (request.EndDate.HasValue)
            {
                var end = request.EndDate.Value;
                if (end.TimeOfDay == TimeSpan.Zero) end = end.Date.AddDays(1).AddTicks(-1);
                p["EndDate"] = end;
            }
            if (!string.IsNullOrWhiteSpace(request.OrderStatus)) p["OrderStatus"] = request.OrderStatus;
            if (!string.IsNullOrWhiteSpace(request.BusinessStatus)) p["BusinessStatus"] = request.BusinessStatus;
            if (!string.IsNullOrWhiteSpace(request.Warehouse)) p["Warehouse"] = request.Warehouse;
            return p;
        }

        private byte[] ExportToExcel(DataTable dt)
        {
            using var workbook = new XLWorkbook();
            var sheetName = string.IsNullOrWhiteSpace(dt.TableName) ? "Sheet1" : dt.TableName;
            var worksheet = workbook.Worksheets.Add(dt, sheetName);
            worksheet.SheetView.FreezeRows(1);
            worksheet.Columns().AdjustToContents();
            using var ms = new MemoryStream();
            workbook.SaveAs(ms);
            return ms.ToArray();
        }
    }
}
